
package scalaSci

import scalaSci.math.LinearAlgebra.LinearAlgebra
import scalaSci.math.array.DoubleArray

// methods defined for Array[Double]

  object DoubleArr {


def  Var(v: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.variance(v);
     r
 }


def correlation(v1: Array[Double], v2: Array[Double]): Double = {
      covariance(v1, v2)/ Math.sqrt(scalaSci.math.array.StatisticSample.variance(v1)*scalaSci.math.array.StatisticSample.variance(v2))
  }  


 def  covariance( v1:Array[Double], v2: Array[Double]) = {    // TODO: check
   var n = v1.length
   var degrees = n-1
   var c = 0.0;  var s1 = 0.0;  var  s2 = 0.0
   var k=1
   while  (k< n)  {
       s1 += v1(k);   s2 += v2(k); k+=1
   }
   s1 /= n;  s2 /= n
   k=1
   while  (k< n)  {     c += (v1(k)-s1)*(v2(k)-s2);  k+=1 }
    var  X = c / degrees
    X
   }


def variance(v: Array[Double]): Double = {
  var r = Var(v)
  r
}

def  std(v: Array[Double]): Double =   {
     var r = scalaSci.math.array.StatisticSample.stddeviation(v);
     r
 }

def stddeviation(v: Array[Double]): Double = {
  var r = std(v)
  r
}

  def  T(Md: Array[Array[Double]]): Array[Array[Double]] =  {
    return  DoubleArray.transpose( Md )
	}




def  mean(v: Array[Double]): Double =  {
       var  mn = 0.0
       var  m = v.length
       var i=0
       while  (i < m) {
            mn += v(i)
            i += 1
          }
        mn /=  m;
       mn
    }


def min(v: Array[Double]): Double = {
  var mn=v(0)
  for (k<-1 to v.length)
    if (v(k) < mn) mn=v(k)
mn
}

def max(v: Array[Double]): Double = {
  var mx=v(0)
  for (k<-1 to v.length)
    if (v(k) > mx) mx=v(k)
mx
}


def sum(v: Array[Double]): Double = {
    var sm = 0.0
    var m = v.length
    var i=0
    while (i < m) {
        sm += v(i)
        i += 1
    }
    sm
}

def prod(v: Array[Double]): Double = {
    var pd = 1.0
    var m = v.length
    var i=0
    while (i < m) {
        pd *= v(i)
        i += 1
    }
    pd
}

 def  Inc(begin: Double, pitch: Double,  end: Double): Array[Double] = {
     var siz = ((end - begin) / pitch).asInstanceOf[Int]
     var doubleArr = new Array[Double](siz)
     var i=0;  while (i < siz) {   doubleArr(i) = begin + i * pitch;  i += 1;  }
  doubleArr
	}

def Ones(n:Int): Array[Double] = {
          var v = new Array[Double](n)
          var i=0;    while (i<n)  {   v(i) = 1.0;    i += 1; }
         v
  }

def  Zeros(n: Int): Array[Double] = {
          var v = new Array[Double](n)
          var i=0;  while (i<n)  { v(i) =0.0; i += 1; }
         v
  }

def  Fill(n:Int, value: Double): Array[Double] = {
         var v = new Array[Double](n)
         var i=0;  while (i < n) {  v(i) = value; i += 1; }
         v
  }


 def sin(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.sin(vin(i))
          i += 1
      }
      v
  }

def cos(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.cos(vin(i))
          i += 1
      }
      v
  }

def tan(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.tan(vin(i))
          i += 1
      }
      v
  }


  def asin(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.asin(vin(i))
          i += 1
      }
      v
  }


 def acos(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.acos(vin(i))
          i += 1
      }
      v
  }



def atan(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.atan(vin(i))
          i += 1
      }
      v
  }



def sinh(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.sinh(vin(i))
          i += 1
      }
      v
  }


def cosh(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.cosh(vin(i))
          i += 1
      }
      v
  }



  def tanh(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.tanh(vin(i))
          i += 1
      }
      v
  }



def exp(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.exp(vin(i))
          i += 1
      }
      v
  }


    def log(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.log(vin(i))
          i += 1
      }
      v
  }



def log2(vin: Array[Double]): Array[Double] = {
      var conv = java.lang.Math.log(2.0)
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.log(vin(i))/conv
          i += 1
      }
      v
  }


def log10(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.log10(vin(i))
          i += 1
      }
      v
  }

def abs(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.abs(vin(i))
          i += 1
      }
      v
  }



def ceil(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.ceil(vin(i))
          i += 1
      }
      v
  }


def floor(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.floor(vin(i))
          i += 1
      }
      v
  }



def round(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.round(vin(i))
          i += 1
      }
      v
  }

def sqrt(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.sqrt(vin(i))
          i += 1
      }
      v
  }

def toDegrees(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math.toDegrees(vin(i))
          i += 1
      }
      v
  }



def toRadians(vin: Array[Double]): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math. toRadians(vin(i))
          i += 1
      }
      v
  }


def pow(vin: Array[Double], exponent:Double): Array[Double] = {
      var  n = vin.length
      var  v = new Array[Double](n)
      var i=0
      while (i<n)  {
          v(i) =  java.lang.Math. pow(vin(i), exponent)
          i += 1
      }
      v
  }



def  Rand(n:Int): Array[Double] = {
  var v = new Array[Double](n)
  var i=0;  while (i < n) {    v(i) =  java.lang.Math.random; i += 1;  }
 v
}

}


/*
    public static double[] mean(double[][] v) {
        int m = v.length;
        int n = v[0].length;
        double[] mean = new double[n];
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                mean[j] += v[i][j];
        for (int j = 0; j < n; j++)
            mean[j] /= (double) m;
        return mean;
    }
*/


